package com.whately.core.database.db;

import com.whately.core.database.vo.DatabaseTxPackageVO;
import org.apache.commons.lang3.StringUtils;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DatabaseCfgConstant {

    /******************************************************************************
     * 静态变量和方法
     *****************************************************************************/

    //默认库的key
     static String DEFAULT_DATABASE_SCHEMA = StringUtils.EMPTY;

    //非主库的mapper文件
     static Map<String, String> MAPPERS_SCHEMA_INFO = new HashMap<>();

    //按照schema格式存储，数据源
     static Map<String, List<DataSource>> DATABASE_GROUP_BY_SCHEMA = new HashMap<>();

     //tx
    static Map<String, DatabaseTxPackageVO> TX_POINT_MAP = new HashMap<>();

    /*****************************************************************************
     * 获取默认数据源
     ****************************************************************************/
    public static String getDefaultDatabaseSchema() {
        return DEFAULT_DATABASE_SCHEMA;
    }

    public static DataSource getDatasourceDefault(){
        return getDatasourceBySchema(DEFAULT_DATABASE_SCHEMA);
    }

    public static DataSource getDatasourceBySchema(String schema){
        if(StringUtils.isBlank(schema)){
            return null;
        }
        if(DATABASE_GROUP_BY_SCHEMA.get(schema)!=null&&DATABASE_GROUP_BY_SCHEMA.get(schema).size()>0){
            return DATABASE_GROUP_BY_SCHEMA.get(schema).get(0);
        }
        return null;
    }
    /*****************************************************************************
     * 数据源路由选择
     ****************************************************************************/
    //public static String router(String mapperNamespace, String statementId) {
    public static String router(String mapperNamespace) {
        //获取DAO对应的数据库集群
        String schema = MAPPERS_SCHEMA_INFO.get(mapperNamespace);
        if (schema == null) {
            schema = DEFAULT_DATABASE_SCHEMA;
        }

        /**选择数据源

         //禁止删除操作,并记录错误日志
         //        if (delete.matcher(statementId).matches()) {
         //            //logger.warn("router databsource warning, delelte operation is forbiden, dao[{}], statement[{}]. ",
         //            //		mapperNamespace,statementId);
         //
         //            //暂时放开
         //            //return null ;
         //        }

         String[] dataSourceArr = MultiDataSourceRouter.getDataSourceArrBySchema(schema);
         if (dataSourceArr == null || dataSourceArr.length == 0) {
         logger.error("schema[{}]'datasources is null ,maybe cobar has been offline!!", schema);
         throw new RuntimeException("schema[" + schema + "]'datasources is null ,mybe cobar has been offline!!");
         }
         //默认使用数据库集群中第一个数据源  即master
         String dataSource = dataSourceArr[MASTER_INDEX];

         if (CobarHelper.isCobarSchema(schema)) {
         dataSource = dataSourceArr[randomIndex(dataSourceArr.length)];
         logger.debug("the cobar default cluserName is [{}],and the cobar clusterName is [{}] in database.yml",
         CobarWatcher.DEFAUL_COBAR_CLUSTER_NAME);
         } else {
         //如果为读操作，随机选择一个数据源
         if (select.matcher(statementId).matches()) {
         int index = randomIndex(dataSourceArr.length);
         //读操作是否只在slave上完成
         //因为从北京69数据库读取太慢，所以读操作只在南京的slave
         if (MultiDataSourceRouter.getReadOnlyInSlave()) {
         if (MASTER_INDEX == index && dataSourceArr.length > 1) {
         index = (index + 1) % dataSourceArr.length;
         }
         }

         //在业务逻辑中, 强制走master
         if (ConfigReaderUtil.getBoolean(GLOBAL_FORCE_MASTER_ENABLE, true) &&
         Boolean.TRUE.equals(DatabaseRouting.isForceMaster())) {
         index = MASTER_INDEX;
         logger.debug("force router datasource to master");
         }

         logger.debug("router datasource in cluster, size[{}], datasource index[{}] in dataSourceArr[{}]",
         dataSourceArr.length, index, dataSourceArr);

         dataSource = dataSourceArr[index];
         }
         }

         logger.debug("datasource router result is [{}], choose by dao[{}] & statementid[{}] in cluster[{}]",
         dataSource, mapperNamespace, statementId, schema);
         */
        return schema;
    }
}
